package com.qianya.weishi_server.config.security;

import com.alibaba.fastjson.JSON;

import com.qianya.weishi_server.common.result.GenericErrorCode;
import com.qianya.weishi_server.common.exception.GenericException;
import com.qianya.weishi_server.common.result.CommonResult;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 鉴权
 *
 * @author LLL
 */
@Slf4j
public class TokenAuthenticationFilter extends OncePerRequestFilter {

    private AuthenticationManager authenticationManager;

    TokenAuthenticationFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//        UserServiceImpl userService = SpringBean.getBean(UserServiceImpl.class);
        String uri = request.getRequestURI();
        log.debug("请求地址：{}", uri);
        /* 已认证直接返回 */
        if (SecurityContextHolder.getContext().getAuthentication() != null) {
            filterChain.doFilter(request, response);
            return;
        }
        try {
            StatelessTokenAuthentication authentication = new StatelessTokenAuthentication(request, response);
            Authentication authResult = authenticationManager.authenticate(authentication);
            if (!authResult.isAuthenticated()) {
                responseJson(response, new CommonResult<>(GenericErrorCode.TOKEN_VALID_ERROR));
                return;
            }
            Claims claims = (Claims) authResult.getPrincipal();
            if (!claims.containsKey("genericId")) {
                responseJson(response, new CommonResult<>(GenericErrorCode.TOKEN_VALID_ERROR));
                return;
            }
//            String cacheKey = claims.get("genericId").toString();
//            String cacheValue = cacheService.findToken(cacheKey);
//            if (Strings.isNullOrEmpty(cacheValue)) {
//                responseJson(response, new SingleResult<>(GenericErrorCode.TOKEN_TIMEOUT_ERROR));
//                return;
//            }
//            cacheService.saveToken(cacheKey, cacheValue);
            SecurityContextHolder.getContext().setAuthentication(authResult);
            filterChain.doFilter(request, response);
        } catch (GenericException e) {
            responseJson(response, new CommonResult<>(e.getErrorCode()));
        }
    }

    private void responseJson(HttpServletResponse response, CommonResult result) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(JSON.toJSONString(result));
    }
}
